#pragma once

#include "Thread.h"
#include "IpcBuff.h"

#include <queue>



class CIpcServer 
{
public:
	CIpcServer(void);
	~CIpcServer(void);

public:
	typedef   queue<CIpcBuff*>					 CacheQueue;
	typedef function<void (long,char*,int)>		 RecvCallBack;
	typedef function<void (long,int)>            EventCallBack;

private:
	 SOCKET								m_ListenSock;
	 SOCKET								m_ClientSock;
	 CThread							m_AcceptThread;
	 CThread							m_SendThread;
	 CThread							m_RecvThread;
	 BOOL								m_bStart;
	 BOOL								m_bEnableHeartBeat;
	 CacheQueue							m_SendQueue;
	 unsigned int						m_nHeartBeatTimeOutRef;
	 RecvCallBack						m_lpfnRecvCallBack;
	 EventCallBack						m_lpfnEventCallBack;
	 unsigned int						m_nCurrentEvent;
	
protected:
      

public: 
	int  Start(int nPort);	
	void Send(char* buff, int len);
	void EnableHeartBeat(bool bEnable);
	
	template<typename T> 
	void RegsitRecvCallBack(T* obj,void (T::* lpmemberfn)(long,char*,int ) )
	{
		m_lpfnRecvCallBack = tr1::bind(lpmemberfn,obj,_1,_2,_3);    
	}

	template<typename T> 
	void RegsitEventCallBack(T* obj,void (T::* lpmemberfn)(long,int ) )
	{
		m_lpfnEventCallBack = tr1::bind(lpmemberfn,obj,_1,_2);    
	}

protected:	
    void AcceptThread(LPVOID lpParam);
	void SendThread(LPVOID lpParam);
	void RecvThread(LPVOID lpParam);
	int  Recv(SOCKET sock,char* buf,int lenth,int flag = 0);
	int  Send(SOCKET sock,char* buf,int lenth,int flag = 0);
	void RemoveSendQueue();
	void Disconnect(void);

public:
	
protected:
	void DispatchEvent(long lHandle, int nEvent);
};
